package com.test.qpbgboot.base.enums;

import com.test.qpbgboot.base.exception.ServiceException;
import com.test.qpbgboot.base.response.JsonResult;
import com.test.qpbgboot.base.response.ResultStatus;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/v1/enum")
@Slf4j
@Api(tags = "enum module")
public class EnumController {

    private static final String LOCAL_PATH = "com.tedu.qpbgboot.base.enums";

    @GetMapping("/select/{enumName}")
    @ApiOperation("枚举查询")
    public JsonResult selectEnum(@PathVariable @ApiParam(value = "枚举类名称",
            name = "enumName",required = true) String enumName) {
        log.debug("枚举查询:enumName={}", enumName);
        try {
            Class<?> cls = Class.forName(LOCAL_PATH + "." + enumName+"Enum");
            if (!Enum.class.isAssignableFrom(cls)) {
                throw new IllegalArgumentException("The specified class is not an enum type.");
            }
            List<EnumValueLabel> enumValueList = getEnumValueLabel(cls);
            return JsonResult.success(enumValueList);
        } catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            throw new ServiceException(ResultStatus.ILLEGAL_ARGUMENT);
        }
    }

    private List<EnumValueLabel> getEnumValueLabel(Class<?> cls) throws NoSuchMethodException,
            InvocationTargetException, IllegalAccessException {
        List<EnumValueLabel> enumValueList = new ArrayList<>();
        Method getValue = cls.getMethod("getValue");
        Method getLabel = cls.getMethod("getLabel");
        for (Object enumConstant: cls.getEnumConstants()) {
            String value = (String) getValue.invoke(enumConstant);
            String label = (String) getLabel.invoke(enumConstant);
            enumValueList.add(new EnumValueLabel(value, label));
        }
        return enumValueList;
    }

    @Getter
    private static class EnumValueLabel {
        private final String value;
        private final String label;
        public EnumValueLabel(String value, String label) {
            this.value = value;
            this.label = label;
        }
    }

    public static boolean checkContain(String value, String enumName) {
        if (value==null || value.trim().isEmpty()) {
            return false;
        }
        try {
            Class<?> cls = Class.forName(LOCAL_PATH + "." + enumName+"Enum");
            if (!Enum.class.isAssignableFrom(cls)) {
                throw new IllegalArgumentException("The specified class is not an enum type.");
            }
            Method getValue = cls.getMethod("getValue");
            for (Object enumConstant: cls.getEnumConstants()) {
                if (value.equals(getValue.invoke(enumConstant))) {
                    return true;
                }
            }
        } catch (ClassNotFoundException | InvocationTargetException
                 | NoSuchMethodException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return false;
    }
}
